﻿using LibraryManagement.Custom_Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using System.Windows.Forms;
using LibraryManagement.Custom_Controls.Data_Grid_View;

namespace LibraryManagement.Inventory
{
    public partial class InvBookAdd : libForm
    {
        private LibManagementEntities context;
        private BookDetail OBookDetail;
        public enum Redirection { Add = 1, Edit = 2, Delete = 3 }
        public Redirection eRedirection;
        private bool frmAuthorsLocationSet;
        private libTextBox txtAuthor2;
        private libTextBox txtAuthor3;
        private string author2;
        private string author3;
        private libForm frmAuthors;
        private decimal bookId;
        private InvBookUpdation invBookUpdation;
        private BookCopy OBookCopy;
        private decimal previousLibCode;
        private bool onLoadCompleted = false;
        private bool boolBulkUpdate = false;
        private decimal mainBookLibCode;
        private List<decimal> listTransactionBookLibCode, listCopiesBookLibCode;
        private bool isFormValidated;

        public InvBookAdd()
        {
            InitializeComponent();
            eRedirection = Redirection.Add;
            context = new LibManagementEntities();
        }

        public InvBookAdd(decimal bookId, InvBookUpdation invBookUpdation, Redirection redirection)
        {
            InitializeComponent();
            eRedirection = redirection;
            context = new LibManagementEntities();
            this.bookId = bookId;
            this.invBookUpdation = invBookUpdation;
        }

        private void InvBookAdd_Load(object sender, EventArgs e)
        {
            cmbLocation.SetDataSource(context.Locations.ToList(), "LocationName", "LocationId");

            if (eRedirection == Redirection.Edit)
            {
                listTransactionBookLibCode = context.BookTransactions.Where(x => x.UserId == clsStatics.currentUserId).Select(x => x.BookLibCode).ToList();
                FillControls();
                mainBookLibCode = nudLibCode.Value;
                nudCopies.Enabled = false;
                onLoadCompleted = true;
                if (listTransactionBookLibCode.Contains(mainBookLibCode))
                    nudLibCode.Enabled = false;
                var listBookTransaction = context.BookTransactions.Select(x => x.BookId).ToList();
                if (listBookTransaction.Contains(bookId))
                {
                    boolBulkUpdate = false;
                }
                else
                    boolBulkUpdate = true;
            }
            else if (eRedirection == Redirection.Delete)
            {
                libDataGridViewColumnDelete btndel = new libDataGridViewColumnDelete();
                btndel.Text = "X";
                btndel.HeaderText = "X";
                btndel.Width = 20;
                dgvBookCodes.Columns.Insert(0, btndel);
                FillControls();
                DisableControls();
            }
            else
                nudCopies.Value = 1;
        }

        #region frmAuthors Events & Methods
        private void btnFrmAuthorsShow_Click(object sender, EventArgs e)
        {
            frmAuthors = new libForm();
            frmAuthors.Text = "Add Authors";
            libLabel lblAuthor2 = new libLabel();
            libLabel lblAuthor3 = new libLabel();
            txtAuthor2 = new libTextBox();
            txtAuthor3 = new libTextBox();
            libButton btnAuthorSave = new libButton();
            libButton btnAuthorCancel = new libButton();
            // 
            // lblAuthor2
            // 
            lblAuthor2.AutoSize = true;
            lblAuthor2.Location = new System.Drawing.Point(44, 29);
            lblAuthor2.Name = "lblAuthor";
            lblAuthor2.Size = new System.Drawing.Size(49, 13);
            lblAuthor2.TabIndex = 0;
            lblAuthor2.Text = "Author 2";
            // 
            // lblAuthor3
            // 
            lblAuthor3.AutoSize = true;
            lblAuthor3.Location = new System.Drawing.Point(44, 60);
            lblAuthor3.Name = "lblAuthor3";
            lblAuthor3.Size = new System.Drawing.Size(49, 13);
            lblAuthor3.TabIndex = 1;
            lblAuthor3.Text = "Author 3";
            // 
            // txtAuthor2
            // 
            txtAuthor2.Location = new System.Drawing.Point(119, 25);
            txtAuthor2.Name = "txtAuthor2";
            txtAuthor2.Size = new System.Drawing.Size(100, 20);
            txtAuthor2.TabIndex = 2;
            // 
            // txtAuthor3
            // 
            txtAuthor3.Location = new System.Drawing.Point(119, 56);
            txtAuthor3.Name = "txtAuthor3";
            txtAuthor3.Size = new System.Drawing.Size(100, 20);
            txtAuthor3.TabIndex = 3;
            // 
            // btnAuthorSave
            // 
            btnAuthorSave.Location = new System.Drawing.Point(90, 85);
            btnAuthorSave.Name = "btnAuthorSave";
            btnAuthorSave.Size = new System.Drawing.Size(110, 20);
            btnAuthorSave.TabIndex = 4;
            btnAuthorSave.Text = "Save";
            btnAuthorSave.UseVisualStyleBackColor = true;
            btnAuthorSave.Click += btnAuthorSave_Click;
            // 
            // btnAuthorCancel
            // 
            btnAuthorCancel.Location = new System.Drawing.Point(211, 85);
            btnAuthorCancel.Name = "btnAuthorCancel";
            btnAuthorCancel.Size = new System.Drawing.Size(110, 20);
            btnAuthorCancel.TabIndex = 5;
            btnAuthorCancel.Text = "Cancel";
            btnAuthorCancel.UseVisualStyleBackColor = true;
            btnAuthorCancel.Click += btnAuthorCancel_Click;
            // 
            // frmAuthors
            // 
            frmAuthors.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            //frmAuthors.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            frmAuthors.ClientSize = new System.Drawing.Size(350, 150);
            frmAuthors.Location = new System.Drawing.Point(700, 700);
            frmAuthors.MaximumSize = new System.Drawing.Size(350, 150);
            frmAuthors.MinimumSize = new System.Drawing.Size(350, 150);
            frmAuthors.Load += frmAuthors_Load;
            frmAuthors.LocationChanged += frmAuthors_LocationChanged;
            frmAuthors.Controls.Add(lblAuthor2);
            frmAuthors.Controls.Add(lblAuthor3);
            frmAuthors.Controls.Add(txtAuthor2);
            frmAuthors.Controls.Add(txtAuthor3);
            frmAuthors.Controls.Add(btnAuthorSave);
            frmAuthors.Controls.Add(btnAuthorCancel);
            frmAuthors.Name = "frmAuthors";
            frmAuthorsLocationSet = true;
            frmAuthors.Show();
            //frmAuthors.ResumeLayout(false);
            //frmAuthors.PerformLayout();
        }

        private void frmAuthors_Load(object sender, EventArgs e)
        {
            try
            {
                txtAuthor2.Text = author2;
                txtAuthor3.Text = author3;
            }
            catch (Exception)
            {
                throw;
            }
        }

        void btnAuthorCancel_Click(object sender, EventArgs e)
        {
            frmAuthors.Close();
        }

        void btnAuthorSave_Click(object sender, EventArgs e)
        {
            author2 = txtAuthor2.Text;
            author3 = txtAuthor3.Text;
            frmAuthors.Close();
        }

        void frmAuthors_LocationChanged(object sender, EventArgs e)
        {
            var x = (libForm)sender;
            var lc = x.Location;
            if (frmAuthorsLocationSet)
            {
                x.Location = new System.Drawing.Point(540, 350);
                frmAuthorsLocationSet = false;
            }
        }
        #endregion

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                context = new LibManagementEntities();
                if (eRedirection == Redirection.Add)
                {
                    #region Add Books
                    using (TransactionScope ts = new TransactionScope())
                    {
                        OBookDetail = new BookDetail();
                        OBookDetail.Title = txtTitle.Text;
                        OBookDetail.Author1 = txtAuthor.Text;
                        OBookDetail.Author2 = author2;
                        OBookDetail.Author3 = author3;
                        OBookDetail.Publisher = txtPublisher.Text;
                        OBookDetail.LocationId = (decimal)cmbLocation.SelectedValue;
                        OBookDetail.Copies = (int)nudCopies.Value;
                        OBookDetail.Edition = (int)nudEdition.Value;
                        OBookDetail.YearOfEdition = (int)nudYearOfEdition.Value;
                        OBookDetail.ISBN = nudISBN.Value;
                        OBookDetail.UserId = clsStatics.currentUserId;
                        context.BookDetails.Add(OBookDetail);
                        context.SaveChanges();

                        var bookId = context.BookDetails.Single(x => x.Title == txtTitle.Text).Id;
                        OBookCopy = new BookCopy();
                        OBookCopy.LibCode = nudLibCode.Value;
                        OBookCopy.BookId = bookId;
                        OBookCopy.UserId = clsStatics.currentUserId;
                        context.BookCopies.Add(OBookCopy);
                        context.SaveChanges();

                        foreach (DataGridViewRow row in dgvBookCodes.Rows)
                        {
                            OBookCopy = new BookCopy();
                            OBookCopy.LibCode = Convert.ToDecimal(row.Cells["dgvcBookCode"].Value);
                            OBookCopy.BookId = bookId;
                            OBookCopy.UserId = clsStatics.currentUserId;
                            context.BookCopies.Add(OBookCopy);
                            context.SaveChanges();
                        }
                        ts.Complete();
                    }
                    #endregion
                }
                else if (eRedirection == Redirection.Edit)
                {
                    #region Edit Books
                    try
                    {
                        using (TransactionScope ts = new TransactionScope())
                        {
                            context = new LibManagementEntities();
                            OBookDetail = context.BookDetails.Single(x => x.Id == bookId);
                            OBookDetail.Title = txtTitle.Text;
                            OBookDetail.Author1 = txtAuthor.Text;
                            OBookDetail.Author2 = author2;
                            OBookDetail.Author3 = author3;
                            OBookDetail.Publisher = txtPublisher.Text;
                            OBookDetail.LocationId = (decimal)cmbLocation.SelectedValue;
                            OBookDetail.Copies = (int)nudCopies.Value;
                            OBookDetail.Edition = (int)nudEdition.Value;
                            OBookDetail.YearOfEdition = (int)nudYearOfEdition.Value;
                            OBookDetail.ISBN = nudISBN.Value;

                            if (!boolBulkUpdate)
                            {
                                OBookCopy = context.BookCopies.Single(x => x.LibCode == mainBookLibCode);
                                var bookcpy2 = new BookCopy();
                                bookcpy2.LibCode = nudLibCode.Value;
                                bookcpy2.BookId = OBookCopy.BookId;
                                bookcpy2.UserId = OBookCopy.UserId;
                                context.BookCopies.Remove(OBookCopy);
                                context.BookCopies.Add(bookcpy2);
                            }

                            if (boolBulkUpdate)
                            {
                                if (!(epBookAdd.GetError(lblCopiesLibCode) == "Lib Codes already Exists. Conflicting Entries in Grid.")
                                    && isFormValidated)
                                {
                                    var listBookCopies = context.BookCopies.Where(x => x.BookId == bookId).ToList();
                                    context.BookCopies.RemoveRange(listBookCopies);

                                    OBookCopy = new BookCopy();
                                    OBookCopy.LibCode = nudLibCode.Value;
                                    OBookCopy.BookId = bookId;
                                    OBookCopy.UserId = clsStatics.currentUserId;
                                    context.BookCopies.Add(OBookCopy);

                                    foreach (DataGridViewRow row in dgvBookCodes.Rows)
                                    {
                                        OBookCopy = new BookCopy();
                                        OBookCopy.LibCode = Convert.ToDecimal(row.Cells["dgvcBookCode"].Value);
                                        OBookCopy.BookId = bookId;
                                        OBookCopy.UserId = clsStatics.currentUserId;
                                        context.BookCopies.Add(OBookCopy);
                                    }

                                }
                                else
                                {
                                    return;
                                }
                            }

                            context.SaveChanges();
                            ts.Complete();
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    #endregion
                }
                this.Close();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        private void InvBookAdd_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (eRedirection == Redirection.Edit || eRedirection == Redirection.Delete)
            {
                invBookUpdation.Enabled = true;
                invBookUpdation.SetDataGridView();
            }
        }
        private void nudCopies_ValueChanged(object sender, EventArgs e)
        {
            if (eRedirection != Redirection.Delete)
            {
                var rowCount = dgvBookCodes.Rows.Count;
                var copies = nudCopies.Value;
                var cp = copies - 1;

                if (cp > rowCount && copies > 1)
                {
                    var indexAdd = dgvBookCodes.Rows.Add((int)(cp - rowCount));
                    SetCodes();
                }
                else if (cp < rowCount && copies > 0)
                {
                    var remove = rowCount - cp;
                    while (remove > 0)
                    {
                        dgvBookCodes.Rows.RemoveAt((int)cp);
                        remove--;
                    }
                    SetCodes();
                }
            }
        }
        private void nudLibCode_ValueChanged(object sender, EventArgs e)
        {
            if (dgvBookCodes.Rows.Count > 0 && eRedirection != Redirection.Delete && boolBulkUpdate)
            {
                SetCodes();
            }
            if (eRedirection == Redirection.Edit)
            {
                var libCode = nudLibCode.Value;
                if (listCopiesBookLibCode.Contains(libCode))
                {
                    epBookAdd.SetError(nudLibCode, "Book Code Already Exists");
                    isFormValidated = false;
                }
                else
                {
                    epBookAdd.SetError(nudLibCode, "");
                    isFormValidated = true;
                }
            }
        }
        private void dgvBookCodes_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            previousLibCode = Convert.ToDecimal(dgvBookCodes.Rows[e.RowIndex].Cells["dgvcBookCode"].Value);
        }
        private void dgvBookCodes_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (eRedirection == Redirection.Edit)
            {
                try
                {
                    var row = e.RowIndex;
                    var val = Convert.ToDecimal(dgvBookCodes.Rows[e.RowIndex].Cells["dgvcBookCode"].Value);
                    //ValidateGrid(row, val, false);
                }
                catch (Exception)
                {
                }
            }

        }
        private void dgvBookCodes_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (eRedirection == Redirection.Delete)
                {
                    if (e.RowIndex != -1 && e.ColumnIndex == 0)
                    {
                        using (TransactionScope ts = new TransactionScope())
                        {
                            var libcode = Convert.ToDecimal(dgvBookCodes.Rows[e.RowIndex].Cells["dgvcBookCode"].Value);
                            var OBookCopy = context.BookCopies.Single(x => x.LibCode == libcode);
                            var OBookDetail = context.BookDetails.Single(x => x.Id == OBookCopy.BookId);
                            context.BookCopies.Remove(OBookCopy);

                            dgvBookCodes.Rows.Remove(dgvBookCodes.Rows[e.RowIndex]);
                            nudCopies.Value = dgvBookCodes.Rows.Count + 1;
                            OBookDetail.Copies = (int)nudCopies.Value;
                            context.SaveChanges();

                            ts.Complete();
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                //"The DELETE statement conflicted with the REFERENCE constraint \"FK_BookTransactions_BookCopy\". The conflict occurred in database \"LibManagement\", table \"dbo.BookTransactions\", column 'BookLibCode'.\r\nThe statement has been terminated."
                if (((ex.InnerException).InnerException).Message.Contains("FK_BookTransactions_BookCopy"))
                {
                    MessageBox.Show("This book is at least assigned once to a member.\nCannot delete this book.");
                }
            }
        }
        private void dgvBookCodes_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {

            if (eRedirection == Redirection.Edit)
            {
                #region Editing BookCopy
                if (onLoadCompleted && !boolBulkUpdate)
                {
                    try
                    {
                        var rowIndex = e.RowIndex;
                        var row = dgvBookCodes.Rows[rowIndex];
                        var val = Convert.ToDecimal(dgvBookCodes.Rows[e.RowIndex].Cells["dgvcBookCode"].Value);

                        if (!listTransactionBookLibCode.Contains(val))
                        {
                            var context = new LibManagementEntities();
                            epBookAdd.SetError(lblCopiesLibCode, "");
                            var OBookCopy = context.BookCopies.Single(x => x.LibCode == previousLibCode);

                            var bookcpy2 = new BookCopy();
                            bookcpy2.LibCode = val;
                            bookcpy2.BookId = OBookCopy.BookId;
                            bookcpy2.UserId = OBookCopy.UserId;
                            context.BookCopies.Remove(OBookCopy);
                            context.BookCopies.Add(bookcpy2);

                            context.SaveChanges();
                        }
                        else
                        {
                            row.Cells["dgvcBookCode"].Value = previousLibCode;
                            epBookAdd.SetError(lblCopiesLibCode, "Book Code already Exists.");
                        }

                    }
                    catch (Exception ex)
                    {
                    }
                }
                #endregion

                #region Validating Grid
                try
                {
                    var row = e.RowIndex;
                    var val = Convert.ToDecimal(dgvBookCodes.Rows[e.RowIndex].Cells["dgvcBookCode"].Value);
                    ValidateGrid(row, val, false, listCopiesBookLibCode);
                }
                catch (Exception)
                {
                }
                #endregion
            }

        }

        #region Methods
        private void FillControls()
        {
            OBookDetail = context.BookDetails.Single(x => x.Id == bookId);
            txtTitle.Text = OBookDetail.Title;
            txtAuthor.Text = OBookDetail.Author1;
            author2 = OBookDetail.Author2;
            author3 = OBookDetail.Author3;
            txtPublisher.Text = OBookDetail.Publisher;
            cmbLocation.SelectedValue = OBookDetail.LocationId;
            nudCopies.Value = (decimal)OBookDetail.Copies;
            nudEdition.Value = (decimal)OBookDetail.Edition;
            nudYearOfEdition.Value = (decimal)OBookDetail.YearOfEdition;
            nudISBN.Value = (decimal)OBookDetail.ISBN;

            if (eRedirection == Redirection.Delete)
            {
                dgvBookCodes.Rows.Add((int)(nudCopies.Value - 1));
            }
            var i = -1;
            foreach (var item in context.BookCopies.Where(x => x.BookId == bookId).ToList())
            {
                if (i == -1)
                {
                    nudLibCode.Value = item.LibCode;
                }
                else
                {
                    dgvBookCodes.Rows[i].Cells["dgvcBookCode"].Value = item.LibCode;
                    ValidateGrid(i, item.LibCode, true, listTransactionBookLibCode);
                }
                i++;
            }
        }
        private void DisableControls()
        {
            txtTitle.Enabled = false;
            txtAuthor.Enabled = false;
            txtPublisher.Enabled = false;
            cmbLocation.Enabled = false;
            nudCopies.Enabled = false;
            nudEdition.Enabled = false;
            nudYearOfEdition.Enabled = false;
            nudISBN.Enabled = false;
            nudLibCode.Enabled = false;
            btnFrmAuthorsShow.Enabled = false;

            btnSave.Visible = false;
            btnCancel.Text = "Close";
        }
        private void SetCodes()
        {
            var x = 1;
            epBookAdd.SetError(lblCopiesLibCode, "");
            listCopiesBookLibCode = context.BookCopies.Where(y => y.UserId == clsStatics.currentUserId && y.BookId != bookId).Select(y => y.LibCode).ToList();
            foreach (DataGridViewRow row in dgvBookCodes.Rows)
            {
                var libCode = nudLibCode.Value + x;
                row.Cells["dgvcBookCode"].Value = libCode;
                if (listCopiesBookLibCode.Contains(libCode))
                    epBookAdd.SetError(lblCopiesLibCode, "Lib Codes already Exists. Conflicting Entries in Grid.");
                x++;
            }
        }
        private void ValidateGrid(int rowIndex, decimal libCode, Boolean setRowReadOnly, List<decimal> list)
        {
            if (list.Contains(libCode))
            {
                if (setRowReadOnly)
                {
                    dgvBookCodes.Rows[rowIndex].ReadOnly = true;
                }
                dgvBookCodes.Rows[rowIndex].DefaultCellStyle.BackColor = Color.PaleVioletRed;
            }
            else
            {
                dgvBookCodes.Rows[rowIndex].DefaultCellStyle.BackColor = Color.White;
            }
        }
        #endregion
    }
}
